Writing and Managing `pf.conf`

The `pf.conf` file is the heart of OpenBSD’s `pf` (Packet Filter) firewall. It defines all the rules, options, and configurations for the firewall. This tutorial provides an in-depth guide to writing, organizing, and managing `pf.conf` effectively, with examples and best practices.

Overview of `pf.conf`

The `pf.conf` file is typically located at `/etc/pf.conf`. It is a plain text file that contains the rules and settings for the `pf` firewall. The file is divided into several sections:

  • Macros: Variables for simplifying and reusing values.
  • Tables: Dynamic lists of IP addresses or networks.
  • Options: Global settings for `pf` behavior.
  • Normalization: Rules for normalizing packets.
  • Queueing: Traffic shaping and prioritization rules.
  • Filtering Rules: Rules for allowing or blocking traffic.
  • NAT and Redirection: Rules for Network Address Translation and port forwarding.

Basic Structure of `pf.conf`

Here’s a basic template for a `pf.conf` file:


# Macros
ext_if = "em0"  # External interface
int_if = "em1"  # Internal interface
local_net = "192.168.1.0/24"

# Tables
table  persist

# Options
set skip on lo  # Skip filtering on the loopback interface
set block-policy drop  # Drop packets silently
set loginterface $ext_if  # Log traffic on the external interface

# Normalization
scrub in on $ext_if all fragment reassemble

# NAT
nat on $ext_if from $local_net to any -> ($ext_if)

# Filtering Rules
block all
pass in on $int_if from $local_net to any keep state
pass out on $ext_if proto tcp to port 80 keep state
block in quick from 

Explanation

  • Macros: Simplify the configuration by defining variables for interfaces and networks.
  • Tables: Use dynamic lists for managing IP addresses efficiently.
  • Options: Configure global settings for `pf` behavior.
  • Normalization: Ensure packets are well-formed and reassemble fragments.
  • NAT: Enable NAT for traffic from the internal network to the external interface.
  • Filtering Rules: Define rules for blocking or allowing traffic.

Writing Rules in `pf.conf`

Rules in `pf.conf` are written in a specific format. Here’s a breakdown of the key components:

1. Block and Pass Rules

These rules determine whether traffic is allowed or blocked:


# Block all traffic by default
block all

# Allow incoming SSH traffic
pass in on $ext_if proto tcp to port 22 keep state

2. NAT Rules

NAT rules translate private IP addresses to public IP addresses:


# NAT for internal network
nat on $ext_if from $local_net to any -> ($ext_if)

3. Redirection Rules

Redirect traffic to internal servers:


# Redirect HTTP traffic to an internal web server
rdr on $ext_if proto tcp to port 80 -> 192.168.1.100 port 80

4. Logging Rules

Log specific traffic for monitoring and troubleshooting:


# Log incoming SSH traffic
pass in log on $ext_if proto tcp to port 22 keep state

5. Quick Rules

Quick rules are evaluated immediately and override subsequent rules:


# Block traffic from a specific IP immediately
block in quick from 192.168.1.200

Managing `pf.conf`

Once you’ve written your `pf.conf` file, you need to load and manage it using `pfctl`:

1. Enabling and Reloading `pf`


# Enable pf
pfctl -e

# Load the configuration file
pfctl -f /etc/pf.conf

2. Testing the Configuration

Always test your configuration before applying it:


# Test the syntax of pf.conf
pfctl -nf /etc/pf.conf

3. Viewing Active Rules

Check the currently loaded rules:


pfctl -sr

4. Monitoring Traffic

Use `tcpdump` to monitor traffic in real-time:


tcpdump -n -e -ttt -i pflog0

Best Practices for Managing `pf.conf`

Follow these best practices to ensure your `pf.conf` file is effective and maintainable:

  • Comment Your Rules: Add comments to explain the purpose of each rule.
  • Group Related Rules: Organize rules by function (e.g., NAT, filtering, logging).
  • Use Macros and Tables: Simplify your configuration and make it easier to update.
  • Test Before Applying: Always test your configuration with `pfctl -nf` before reloading it.
  • Enable Logging: Log critical rules to monitor traffic and troubleshoot issues.
  • Backup Configurations: Keep backups of your `pf.conf` file to recover from mistakes or failures.

Advanced Techniques

Here are some advanced techniques for managing `pf.conf`:

1. Dynamic Tables

Use tables to manage large lists of IP addresses dynamically:


table  persist
block in quick from 

Add or remove IPs dynamically:


pfctl -t blocked_ips -T add 192.168.1.100
pfctl -t blocked_ips -T delete 192.168.1.100

2. Anchors

Use anchors to modularize your configuration:


anchor "webserver"
load anchor "webserver" from "/etc/pf.webserver.conf"

Conclusion

Writing and managing `pf.conf` is a critical skill for using OpenBSD’s `pf` firewall effectively. By understanding its structure, syntax, and best practices, you can create powerful and maintainable firewall configurations. In the next tutorial, we’ll explore advanced features of `pf`, including traffic shaping and high availability. Stay tuned!

 

 

Check out some Bands on Bandcamp.com. Seven Times Refined by Altogether Steve and the Mercenaries, Crazy Fingers (Vancouver 1991), Flying Butt Pliers, and Hammy Ham Hands.

Proudly powered by a Text Editor, an IDE, an SFTP client, some Internet searches, and more recently help from some AI.

2025 dispelled.ca end of file.